package org.makcro.sms.services.chat.web.client.mvc;

import java.util.List;

import org.makcro.sms.services.chat.web.client.AppEvents;
import org.makcro.sms.services.chat.web.client.Constants;
import org.makcro.sms.services.chat.web.client.mvc.view.NewMessagesView;
import org.makcro.sms.services.chat.web.client.services.message.MessageService;
import org.makcro.sms.services.chat.web.client.services.message.MessageServiceAsync;
import org.makcro.sms.services.chat.web.shared.dto.QuestionDto;

import com.extjs.gxt.ui.client.Registry;
import com.extjs.gxt.ui.client.event.EventType;
import com.extjs.gxt.ui.client.mvc.AppEvent;
import com.extjs.gxt.ui.client.mvc.Controller;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.rpc.AsyncCallback;

/**
 * Controller for {@link NewMessagesView} and it child elements.
 * Responsible for checking for new request messages (questions) and notifying UI. 
 * @author makcro
 *
 */
public class NewMessagesController extends Controller {
	
	/**
	 * Controlled view instance
	 */
	private NewMessagesView		view;
	
	/**
	 * Instance of {@link MessageService} service used to retreive messages
	 */
	private MessageServiceAsync	messageServiceAsync;
	
	/**
	 * Timer for periodically invoking message retrieval operation.
	 */
	private Timer				timer;

	public NewMessagesController() {
		// subscribe to events
		registerEventTypes( AppEvents.LoginSuccessful );
		registerEventTypes( AppEvents.NEW_MESSAGES_UPDATE );
		registerEventTypes( AppEvents.ANSWER_SENT );
	}

	@Override
	protected void initialize() {
		super.initialize();
		// get instance of message service
		messageServiceAsync = Registry.get( Constants.Services.MessageService );
		view = new NewMessagesView( this );
		
		initTimer();
	}

	/**
	 * Creates and scheduels timer
	 */
	private void initTimer() {
		timer = new Timer() {

			@Override
			public void run() {
				onCheckForNewMessages();

			}
		};
		timer.scheduleRepeating( 60 * 1000 );
	}

	@Override
	public void handleEvent(AppEvent event) {
		EventType type = event.getType();
		if (type == AppEvents.LoginSuccessful) {
			onLoginSuccessful( event );
		}
		else if (type == AppEvents.NEW_MESSAGES_UPDATE) {
			onNewMessagesUpdate( event );
		}
		else if (type == AppEvents.ANSWER_SENT) {
			onCheckForNewMessages();
		}

	}

	private void onNewMessagesUpdate(AppEvent event) {
		onCheckForNewMessages();
	}

	/**
	 * Invokes {@link MessageService#getNewMessages()} and forwards results to view
	 */
	private void onCheckForNewMessages() {
		this.messageServiceAsync.getNewMessages( new AsyncCallback<List<QuestionDto>>() {

			@Override
			public void onSuccess(List<QuestionDto> result) {

				AppEvent appEvent = new AppEvent( AppEvents.NewQuestionsFound, result );
				forwardToView( view, appEvent );

			}

			@Override
			public void onFailure(Throwable caught) {
				System.out.println( caught );

			}
		} );
	}

	/**
	 * Forwards event to the view and calls check for new messages
	 * @param event
	 */
	private void onLoginSuccessful(AppEvent event) {
		forwardToView( view, event );
		onCheckForNewMessages();
	}
}
